/***
 * @Description:本文件是基于消息队列的网络数据交换处理机制实现的C语言文件
 * @Author: Liverpool
 * @Date: 2024-01-21 02:19:46
 * @LastEditTime: 2024-01-21 02:19:55
 * @LastEditors: Liverpool
 */
#include "MessageHander.h"
#include "timer.h"
#include "system.h"
#include "ipv4.h"

static D_FixQueue message_queue;                                // 定义消息队列
static void *message_table[MessageHandler_Message_Cnt];         // 定义消息队列中存储消息的内存指针数组
static D_NetMessage message_buffer[MessageHandler_Message_Cnt]; // 定义消息数据包真正存储的内存结构数组
static D_MemoryBlock message_block;                             // 定义内存管理消息结构性数组的链表

/***
 * @description: 应用程序调用工作线程的测试函数
 * @Author: Liverpool
 * @Date: 2025-05-02 16:12:08
 * @return {*}
 * @param {_message_func} msg 应用程序请求工作线程的消息结构体
 */
net_err_t message_handler_test_func(struct _message_func msg)
{
    plat_printf("hello 1234:0x%x", *(int *)msg.param);
    return NET_ERR_OK;
}

/***
 * @description: 初始化消息处理工作机制的工作线程
 * @Author: Liverpool
 * @Date: 2024-01-21 23:13:45
 * @return {*} 协议栈错误类型
 */
net_err_t message_handler_init(void)
{
    debug_info(Debug_MessageHandler, "message handler init");
    net_err_t err = fix_queue_init(&message_queue, message_table, MessageHandler_Message_Cnt, MessageHandler_Locker_Type); // 对消息队列进行初始化
    if (err < 0)
    {
        debug_error(Debug_MessageHandler, "fix queue init failed");
        return err;
    }
    err = memory_block_init(&message_block, message_buffer, sizeof(D_NetMessage), MessageHandler_Message_Cnt, MessageHandler_Locker_Type); // 对消息队列的内存管理链表进行初始化
    if (err < 0)
    {
        debug_error(Debug_MessageHandler, "memory block init failed");
        return err;
    }
    debug_info(Debug_MessageHandler, "message handler init done");
    return NET_ERR_OK;
}
/***
 * @description: 对网卡的输入队列的数据包进行读取处理
 * @Author: Liverpool
 * @Date: 2024-05-13 02:24:06
 * @return {*} 读取处理过程中的错误
 * @param {D_NetMessage} *msg 工作线程处理发出的网络数据包信息
 */
static net_err_t do_netif_in(D_NetMessage *msg)
{
    D_Net_Interface *netif = msg->msg_netif.netif;
    D_Packet *buf;
    while ((buf = net_interface_get_in(netif, -1))) // 从对应网卡的消息队列中得到数据包
    {
        debug_info(Debug_MessageHandler, "recv a packet");
        // 根据有无链路层协议做消息处理
        if (netif->link_layer) // 比如Ethernet
        {
            net_err_t err = netif->link_layer->in(netif, buf); // 做各自链路层的数据处理
            if (err < 0)
            {
                packet_free(buf);
                debug_Warning(Debug_MessageHandler, "netif in failed, error=%d", err);
            }
        }
        else // 没有链路层(回环网卡)
        {
            net_err_t err = ipv4_in(netif, buf);
            if (err < 0) // ipv4协议解析数据包失败
            {
                packet_free(buf);
                debug_Warning(Debug_MessageHandler, "netif in failed, error=%d", err);
            }
        }
    }
    return NET_ERR_OK;
}

/***
 * @description: 工作线程调用应用程序的请求函数的执行函数
 * @Author: Liverpool
 * @Date: 2024-09-03 00:47:16
 * @return {*}
 * @param {D_Message_Func} *func_msg 工作线程队列中贮存的请求函数执行变量
 */
static net_err_t do_func(D_Message_Func *func_msg)
{
    debug_info(Debug_MessageHandler, "call func");
    func_msg->err = func_msg->func(func_msg);
    sys_sem_notify(func_msg->wait_sem); // 发送通知，释放一个信号量
    debug_info(Debug_MessageHandler, "fuc exec comlete...");
    return NET_ERR_OK;
}

/***
 * @description: 消息处理机制的工作线程，也是协议栈的中心线程
 * @Author: Liverpool
 * @Date: 2024-01-21 23:22:56
 * @return {*}
 * @param {void} *arg
 */
static void worker_thread(void *arg)
{
    debug_info(Debug_MessageHandler, "message handler is running....\n");
    net_time_t time;
    sys_time_curr(&time);
    while (1)
    {
        int first_tmo = net_timer_first_tmo();
        D_NetMessage *message = (D_NetMessage *)fix_queue_receive(&message_queue, first_tmo); // 测试：在工作线程中接收消息队列的消息
        if (message)
        {
            debug_info(Debug_MessageHandler, "recv a message %p:%d", message, message->type);
            switch (message->type)
            {
            case NET_Message_NETIF_In:
                do_netif_in(message);
                break;
            case NET_Message_Func:
                do_func(message->func);
                break;
            default:
                break;
            }
            memory_block_free(&message_block, message); // 处理完消息队列的消息后需要重新释放内存
        }
        int diff_ms = sys_time_goes(&time);
        net_timer_check_tmo(diff_ms);
    }
}

/***
 * @description:消息处理工作机制的工作线程的启动
 * @Author: Liverpool
 * @Date: 2024-01-21 23:14:45
 * @return {*} 协议栈错误类型
 */
net_err_t message_handler_start(void)
{
    sys_thread_t thread = sys_thread_create(worker_thread, (void *)0);
    // 创建的线程不合法那就返回协议栈系统错误
    if (thread == SYS_THREAD_INVALID)
    {
        return NET_ERR_SYS;
    }
    return NET_ERR_OK;
}
/***
 * @description: 消息队列从网卡接收数据包(也可以说成网卡向消息队列发送数据)
 * @Author: Liverpool
 * @Date: 2024-03-05 01:02:13
 * @return {*} 协议栈错误类型
 */
net_err_t message_handler_netif_in(D_Net_Interface *netif)
{
    // 对网卡得到的数据进行处理
    D_NetMessage *message = memory_block_alloc(&message_block, -1); // 从链表中分配一个内存块给该消息(立马分配)
    if (!message)
    {
        debug_Warning(Debug_MessageHandler, "no free message block"); // 没有空余的内存分配给接收到的消息
        return NET_ERR_MEMORY;
    }
    // 消息进行定型
    message->type = NET_Message_NETIF_In; // 该消息类型为网卡消息
    message->msg_netif.netif = netif;     //  绑定网卡的内存地址

    net_err_t err = fix_queue_send(&message_queue, message, -1); // 立即向消息队列发送收到的消息
    if (err < 0)
    {
        debug_Warning(Debug_MessageHandler, "fix queue is full"); // 消息队列已经满了
        memory_block_free(&message_block, message);               // 需要把分配出来的内存块重新分配到空闲内存链表管理中
        return err;
    }
    return err;
}

/***
 * @description:  应用程序请求工作线程的请求函数的注册发送函数
 * @Author: Liverpool
 * @Date: 2024-08-12 00:08:40
 * @return {*}
 * @param {message_hander_func} *func  请求函数的函数地址
 * @param {void} *param 请求函数运行的参数
 */
net_err_t message_handler_func_execute(message_hander_func func, void *param)
{
    // 1.进行func函数变量信息初始化
    D_Message_Func func_msg;
    func_msg.func = func;
    func_msg.param = param;
    func_msg.err = NET_ERR_OK;
    func_msg.thread = sys_thread_self();
    func_msg.wait_sem = sys_sem_create(0);
    if (func_msg.wait_sem == SYS_SEM_INVALID)
    {
        debug_error(Debug_MessageHandler, "error create wait sem...");
        return NET_ERR_MEMORY;
    }
    // 2.向工作线程发送信息请求
    D_NetMessage *message = memory_block_alloc(&message_block, 0); // 从链表中分配一个内存块给该消息(立马分配)
    if (!message)
    {
        debug_Warning(Debug_MessageHandler, "no free message block"); // 没有空余的内存分配给接收到的消息
        sys_sem_free(func_msg.wait_sem);                              // 释放信号量
        return NET_ERR_MEMORY;
    }
    // 消息进行定型
    message->type = NET_Message_Func; // 定义为消息函数执行
    message->func = &func_msg;
    debug_info(Debug_MessageHandler, "begin call fun:%p", func);
    net_err_t err = fix_queue_send(&message_queue, message, 0); // 立即向消息队列发送收到的消息
    if (err < 0)
    {
        debug_error(Debug_MessageHandler, "fix queue is full"); // 消息队列已经满了
        sys_sem_free(func_msg.wait_sem);                        // 释放信号量
        memory_block_free(&message_block, message);             // 需要把分配出来的内存块重新分配到空闲内存链表管理中
        return err;
    }
    sys_sem_wait(func_msg.wait_sem, 0); // 等待请求函数执行完成
    debug_info(Debug_MessageHandler, "end call fun:%p", func);
    // 释放信号量
    sys_sem_free(func_msg.wait_sem);
    return func_msg.err;
}